package work.base.data.queue;

import java.util.concurrent.*;


/**
 * DelayQueue的使用
 */
public class DelayQueueMain {

    public static void main(String[] args) {
        // 创建DelayQueue实例
        DelayQueue<DelayedTask> delayQueue = new DelayQueue<>();

        // 添加延迟任务到队列
        delayQueue.put(new DelayedTask("任务A", 5000)); // 5秒后执行
        delayQueue.put(new DelayedTask("任务B", 3000)); // 3秒后执行
        delayQueue.put(new DelayedTask("任务C", 8000)); // 8秒后执行

        System.out.println("启动时间: " + System.currentTimeMillis());

        // 创建线程池执行延迟任务
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.submit(() -> {
            try {
                // 不断从队列中获取到期的任务并执行
                // take()会阻塞，时间到期之后才会取出数据
                while (true) {
                    DelayedTask task = delayQueue.take();
                    System.out.println("执行任务: " + task + "，当前时间: " + System.currentTimeMillis());
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 主线程休眠10秒后关闭线程池
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executor.shutdown();
    }
}

class DelayedTask implements Delayed {
    private final String name;
    private final long startTime; // 任务执行的时间点

    public DelayedTask(String name, long delayInMillis) {
        this.name = name;
        // 当前时间加上延迟时间得到开始时间
        this.startTime = System.currentTimeMillis() + delayInMillis;
    }

    // 获取剩余延迟时间，返回0表示已到期
    @Override
    public long getDelay(TimeUnit unit) {
        long diff = startTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    // 比较任务的到期时间，用于队列排序
    @Override
    public int compareTo(Delayed other) {
        return Long.compare(this.startTime, ((DelayedTask) other).startTime);
    }

    @Override
    public String toString() {
        return name + " (执行时间: " + startTime + ")";
    }
}
